<script setup lang="ts">
import { Client } from '@stomp/stompjs'
import { onBeforeMount, onBeforeUnmount, onMounted, ref, type Ref, watch } from 'vue'
import { ChatroomMessage } from '@/dto/ChatroomMessage'
import { useLoginStore } from '@/stores/login'
import { useLocalInformationStore } from '@/stores/LocalInformation'
import { useChatroomStore } from '@/stores/ChatroomStore'
import moment from 'moment'
import { microServiceHttpServer } from '@/apis/MicroServiceHttpServer'
import { ApplicationStatusCodeEnum } from '@/enum/ApplicationStatusCodeEnum'
import { ChatroomMessageCodeEnum } from '@/enum/ChatroomMessageCodeEnum'
import { MutationType } from 'pinia'


const loginStore = useLoginStore()
const infoStore = useLocalInformationStore()
const chatroomStore = useChatroomStore()
const messageQueue: Ref<Array<ChatroomMessage>> = ref([])
const username = ref(loginStore.isLogin ? loginStore.user.username : null)
const userId = ref(loginStore.isLogin ? loginStore.user.userid : null)

const messageQueueEl = ref(null)

let haveMoreHistory = false
let lastKeepAliveSuccess = true
const pageSize = 50
let pageNumber = 0
const textarea = ref(null) as Ref<HTMLFormElement | null>
const client = new Client({
  brokerURL: 'wss://www.snowcrystal.world/snowcrystal-chatroom',
  webSocketFactory() {
    return new WebSocket('wss://www.snowcrystal.world/snowcrystal-chatroom')
  },
  debug: function(str) {
    // console.log(str)
  },
  reconnectDelay: 5000,
  heartbeatIncoming: 4000,
  heartbeatOutgoing: 4000
})

client.onConnect = function(frame) {
  this.subscribe('/channel/message', (msg) => {
    let message = JSON.parse(msg.body)
    messageQueue.value.push(message)
  })
}
client.onDisconnect = function(frame) {
  console.log('STOMP 连接断开')
}

loginStore.$subscribe((mutation, state)=>{
  if(state.isLogin === false){

  }
})

function submitMessage() {
  if (textarea.value) {
    let msg = textarea.value.value
    if (msg) {
      client.publish({
        destination: '/chatroom-channel/message',
        body: JSON.stringify(ChatroomMessage.chat(msg, username.value, userId.value))
      })
      textarea.value.value = ""
    } else {
      console.log('说点什么吧')
    }
  }
}

function tryLoadHistory() {
  microServiceHttpServer.retrieveRecentChatroomHistory(pageSize, pageSize * pageNumber)
    .then((response) => {
      let msg = JSON.parse(response.data)
      if (msg.code === ApplicationStatusCodeEnum.HAS_MORE) {
        pageNumber++
        haveMoreHistory = true
        return Promise.resolve(msg.data)
      } else if (msg.code === ApplicationStatusCodeEnum.OK) {
        haveMoreHistory = false
        return Promise.resolve(msg.data)
      } else {
        return Promise.reject()
      }
    }).then((res) => {
    res.push(messageQueue.value)
    messageQueue.value = res
  }, reason => {
    console.log(`拉取历史记录失败:${reason}`)
  })
}

function tryEnter() {
  microServiceHttpServer.tryEnterChatroom(infoStore.fingerprint).then(response => {
    let msg = JSON.parse(response.data)
    if (msg.code === ApplicationStatusCodeEnum.CREATED) {
        chatroomStore.$patch({
          chatroomUser: msg.data
        })
        username.value = msg.data.username
        userId.value = msg.data.id
      console.log('欢迎来到聊天室1')
    } else if (msg.code === ApplicationStatusCodeEnum.USE_NATIVE) {
        username.value = loginStore.user.username
        userId.value = loginStore.user.id
      console.log('欢迎来到聊天室2',username.value,userId.value)
    }
    lastKeepAliveSuccess = true
  }).catch(reason => {
    console.log(`进入聊天室时发生了些问题:${reason}`)
  })
}

function keepAlive() {
  if (lastKeepAliveSuccess) {
    microServiceHttpServer.sendKeepAlive(infoStore.fingerprint).then(response => {
      let msg = JSON.parse(response.data)
      if (msg.code !== ApplicationStatusCodeEnum.OK) {
        lastKeepAliveSuccess = false
      }
    })
  } else {
    tryEnter()
  }
}

onMounted(()=>{
  watch(messageQueue,()=>{
    messageQueueEl.value.scrollTop = messageQueueEl.value.scrollHeight;
  })
})

onBeforeMount(() => {
  if(loginStore.isLogin){
    chatroomStore.$patch({
      chatroomUser:{
        userId: loginStore.user.id,
        username: loginStore.user.username,
        fingerprint:infoStore.fingerprint,
      }
    })
  }

    loginStore.$subscribe((mutation,state)=>{
      if(mutation.type=== MutationType.patchObject && state.isLogin){
        chatroomStore.$patch({
          chatroomUser:{
            userId: state.user.id,
            username: state.user.username,
            fingerprint:infoStore.fingerprint,
          }
        })
        username.value = state.user.username
        userId.value = state.user.id
      }
      else if(mutation.type=== MutationType.patchObject && !state.isLogin){
        chatroomStore.$reset()
        username.value = null
        userId.value = null
      }
      tryEnter()
    })

  tryEnter()
  setInterval(keepAlive, 30000)
  tryLoadHistory()
  client.activate()
})
onBeforeUnmount(() => {
  client.unsubscribe('/channel/message')
  client.deactivate()
})

</script>

<template>
  <aside class="chatroom__right__root">
    <div class="message__list" ref="messageQueueEl">
      <div  v-for="message in messageQueue" :key="message.timestamp">
        <template v-if="message.id !== '0' ">
          <span>{{ moment(message.timestamp).calendar() }}</span>&nbsp;
          <span v-if="!message.id || (message.id && (message.id.charAt(0) ==='#'))">{{ message.username }}</span>
          <a href="#" v-else>{{message.username}}</a>
          : <span>{{ message.message }}</span>
        </template>
        <template v-else>
            <div style="display: flex;align-items: center;">
                <span>{{message.message}}</span>
              <span v-if="message.code === ChatroomMessageCodeEnum.ENTER">进入了放映室</span>
            </div>
        </template>
      </div>
    </div>
    <div class="chatroom__box">
      <textarea ref="textarea"></textarea>
      <input type="submit" value="发射" @click.prevent="submitMessage" />
    </div>
  </aside>
</template>

<style scoped lang="scss">
.chatroom__right__root {
  display: grid;
  background-color: #9cade5;
  grid-row-gap: var(--spacing-xs);
  grid-template-rows: 6fr 1fr;
}

.message__list {
  overflow-y: scroll;
  background-color: #706eff;
  height: 800px;
}
</style>